package cn.ncu.wechat.service.impl;


import cn.ncu.wechat.dao.MemberLevelMapper;
import cn.ncu.wechat.dao.OrdersMapper;
import cn.ncu.wechat.model.MemberLevel;
import cn.ncu.wechat.model.dto.LeveDTO;
import cn.ncu.wechat.model.dto.UserInfoDetailDTO;
import cn.ncu.wechat.model.dto.UserRegistry;
import cn.ncu.wechat.vo.OrderVo;
import cn.ncu.wechat.vo.UserVo;
import cn.ncu.wechat.util.Result;
import cn.ncu.wechat.util.StringUtil;
import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.ncu.wechat.model.User;
import cn.ncu.wechat.service.UserService;
import cn.ncu.wechat.dao.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author 
 * @description 针对表【user(用户表)】的数据库操作Service实现
 * @createDate 2025-01-07 14:39:44
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
        implements UserService{
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private OrdersMapper ordersMapper;

    @Autowired
    private MemberLevelMapper memberLevelMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Value("${cn.ncu.key}")
    private String key;
    @Value("${cn.ncu.vxValidTime}")
    private int vxValidTime;
    public Result<?> login(UserVo u, String code){
        try {
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("phone",u.getPhone());
            queryWrapper.eq("nick_name",u.getNickName());
            User getUser = userMapper.selectOne(queryWrapper);
            if (getUser!=null){
                //System.out.println("登录成功");
                u.setId(getUser.getId());
                u.setPoints(getUser.getPoints());
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("userInfo", u);
                String token = JWT.create()
                        .withClaim("id", u.getId())
                        .withClaim("code",code)
                        .withExpiresAt(new Date(System.currentTimeMillis() + vxValidTime))//设置失效时间
                        .sign(Algorithm.HMAC256(key));//设置秘钥
                jsonObject.put("token", token);
                redisTemplate.opsForValue().set(token,"user",7, TimeUnit.DAYS);
                return Result.success(jsonObject);
            }
            else {
                return Result.error(404,"会员信息有误或不存在");
            }
        }catch (Exception e){
            return Result.error(500,"服务器异常:"+e);
        }
    }

    public boolean checkURL(DecodedJWT decodedJWT){
        boolean flag = false;
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.select("id");
        queryWrapper.eq("id",decodedJWT.getClaim("id").asLong());
        User user = userMapper.selectOne(queryWrapper);
        if (user!=null){
            // 获取过期时间（exp），返回的是时间戳
            long exp = decodedJWT.getClaim("exp").asLong();
            // 将时间戳转换为Date对象
            Date expiresAt = new Date(exp * 1000L);
            // 获取当前时间
            Date now = new Date();
            // 计算过期时间与当前时间的差值（毫秒）
            long diffInMillies = expiresAt.getTime() - now.getTime();
            // 将毫秒转换为小时
            long diffInHours = diffInMillies / (60 * 60 * 1000);
            redisTemplate.opsForValue().set(decodedJWT.getToken(),"user",diffInHours, TimeUnit.HOURS);
            flag = true;
        }
        return flag;
    }

    public Result<?> getUserInfo(String token){
        if(StringUtil.IsNotNull(token)){
            try {
                Algorithm algorithm = Algorithm.HMAC256(key);//设置加密方式
                JWTVerifier jwtVerifier = JWT.require(algorithm).build();//创建认证对象
                System.out.println("token="+token);
                DecodedJWT decodedJWT = jwtVerifier.verify(token.substring(7));
                QueryWrapper<User> queryWrapper = new QueryWrapper<>();
                queryWrapper.select("id", "nick_name", "avatar_url", "phone", "points", "register_time");
                queryWrapper.eq("id",decodedJWT.getClaim("id").asLong());
                User getUser = userMapper.selectOne(queryWrapper);
                return Result.success(getUser);
            }catch (JWTDecodeException e){
                System.out.println(400);
                return Result.error(400,"秘钥格式错误！");
            } catch (SignatureVerificationException e){
                System.out.println(2005);
                return Result.error(400,"秘钥错误！");
            } catch (TokenExpiredException e) {
                System.out.println(2006);
                return Result.error(400,"未登录或token已过期");
            } catch (Exception e){
                e.printStackTrace();
                return Result.error(500,"服务器错误");
            }
        }
        return Result.error(401,"未登录或token已过期");
    }

    public Result<?> getRegisterRecord(Integer page,Integer pageSize,String starDate,String endDate){
        try{
            Page<UserRegistry> userRegistryPage = new Page<>(page,pageSize);
            Page<UserRegistry> userRegistry = userMapper.getRegistry(starDate,endDate,userRegistryPage);
            JSONObject jsonObject = new JSONObject();
            System.out.println(userRegistry);
            jsonObject.put("list",userRegistry.getRecords());
            jsonObject.put("total",userRegistry.getTotal());
            return Result.success(jsonObject);
        }catch (Exception e){
            return Result.error(500,"服务器异常"+e);
        }
    }

    public Result<?> searchUserListByKeyWord(String keyword,Integer page,Integer pageSize){
        try{
            List<User> userList = null;
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            if (StringUtil.IsNotNull(keyword)) queryWrapper.like("phone",keyword).or().like("nick_name",keyword);
            Page<User> pageInfo = new Page<>(page, pageSize);
            Page<User> userPage = userMapper.selectPage(pageInfo,queryWrapper);
            userList = userPage.getRecords();
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("list",userList);
            jsonObject.put("total",userPage.getTotal());
            return Result.success(jsonObject);
        }catch (Exception e){
            return Result.error(500,"服务器异常"+e);
        }
    }

    public Result<?> getMemberDetail(Integer id){
        try{
            UserInfoDetailDTO userInfoDetailDTO = userMapper.getUserInfoDetailDTO(id);
            System.out.println("----------------------"+userMapper.getUserInfoDetailDTO(id));
            if (userInfoDetailDTO!=null){
                System.out.println("userInfoDetailDTO.getLevelId()==="+userInfoDetailDTO.getLevelId());
                LeveDTO leveDTO = memberLevelMapper.getLeveInfoById(userInfoDetailDTO.getLevelId());
                userInfoDetailDTO.setLevel(leveDTO);
                userInfoDetailDTO.setLevelId(null);
                return Result.success(userInfoDetailDTO);
            } else {
                return Result.fail(404,"用户不存在");
            }
        }catch (Exception e){
            return Result.error(500,"服务器异常"+e);
        }
    }
    public Result<?> getMemberOrders(Long id,Integer page,Integer pageSize,Integer status){
        try{
            Page<OrderVo> pageInfo = new Page<>(page,pageSize);
            Page<OrderVo> orderVoPage = ordersMapper.getOrderByUId(pageInfo,status,id);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("list",orderVoPage.getRecords());
            jsonObject.put("total",orderVoPage.getTotal());
            return Result.success(jsonObject);
        }catch (Exception e){
            return Result.error(500,"服务器异常"+e);
        }
    }

    public Result<?> CountMember(){
        try{
            return Result.success(userMapper.countMembers());
        }catch (Exception e){
            return Result.error(500,"服务器异常"+e);
        }
    }
}